package com.yywq.utils;

import com.yywq.constant.Constant;
import com.yywq.error.BusinessException;
import com.yywq.error.EnumBusinessError;
import com.yywq.pojo.model.UserToken;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.jose4j.keys.HmacKey;
import org.springframework.stereotype.Component;

import java.security.Key;

/**
 * @author: 吴磊
 * @program: yywq_parent
 * @create: 2021-04-14 09:41
 */
@Component
public class TokenUtils {
    /**
     * 生成Token
     *
     * @param userToken
     * @return
     * @throws Exception
     */
    public String generateToken(UserToken userToken) throws Exception {
        JwtClaims claims = new JwtClaims();
        claims.setSubject(userToken.getRealName());
        claims.setClaim(Constant.CONTEXT_USER_ID, userToken.getId());
        claims.setClaim(Constant.CONTEXT_NAME, userToken.getNickName());
        claims.setExpirationTimeMinutesInTheFuture(60 * 24);

        Key key = new HmacKey(Constant.JWT_PRIVATE_KEY.getBytes("UTF-8"));

        JsonWebSignature jws = new JsonWebSignature();
        jws.setPayload(claims.toJson());
        jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256);
        jws.setKey(key);
        jws.setDoKeyValidation(false); // relaxes the key length requirement

        //签名
        String token = jws.getCompactSerialization();
        return token;
    }


    /**
     * 从Token中获取信息
     *
     * @param token
     * @return
     * @throws Exception
     */
    public UserToken getInfoFromToken(String token) throws Exception {

        if (token == null) {
            return null;
        }

        Key key = new HmacKey(Constant.JWT_PRIVATE_KEY.getBytes("UTF-8"));

        JwtConsumer jwtConsumer = new JwtConsumerBuilder()
                .setRequireExpirationTime()
                .setAllowedClockSkewInSeconds(30)
                .setRequireSubject()
                .setVerificationKey(key)
                .setRelaxVerificationKeyValidation() // relaxes key length requirement
                .build();
        JwtClaims processedClaims;
        try {
            processedClaims = jwtConsumer.processToClaims(token);
        } catch (Exception e) {
            throw new BusinessException(EnumBusinessError.USER_NOT_LOGIN, "登录过期，请重新登录");
        }


        return new UserToken(
                processedClaims.getClaimValue(Constant.CONTEXT_USER_ID).toString(),
                processedClaims.getClaimValue(Constant.CONTEXT_NAME).toString(),
                processedClaims.getSubject());
    }
}
